/**
 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ECMASCRIPT_RUNTIME_CALL_ID_H
#define ECMASCRIPT_RUNTIME_CALL_ID_H

#include "plugins/ecmascript/runtime/base/config.h"

namespace ark::ecmascript {
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define INTERPRETER_CALLER_LIST(V)     \
    V(RunInternal)                     \
    V(Ldnan)                           \
    V(Ldinfinity)                      \
    V(Ldglobalthis)                    \
    V(Ldundefined)                     \
    V(Ldboolean)                       \
    V(Ldnumber)                        \
    V(Ldstring)                        \
    V(Ldbigint)                        \
    V(Ldnull)                          \
    V(Ldsymbol)                        \
    V(Ldfunction)                      \
    V(Ldglobal)                        \
    V(Ldtrue)                          \
    V(Ldfalse)                         \
    V(Tonumber)                        \
    V(Toboolean)                       \
    V(Add2Dyn)                         \
    V(Sub2Dyn)                         \
    V(Mul2Dyn)                         \
    V(Div2Dyn)                         \
    V(Mod2Dyn)                         \
    V(EqDyn)                           \
    V(NotEqDyn)                        \
    V(LessDyn)                         \
    V(LessEqDyn)                       \
    V(GreaterDyn)                      \
    V(GreaterEqDyn)                    \
    V(StrictNotEqDyn)                  \
    V(StrictEqDyn)                     \
    V(Shl2Dyn)                         \
    V(Shr2Dyn)                         \
    V(Ashr2Dyn)                        \
    V(And2Dyn)                         \
    V(Or2Dyn)                          \
    V(Xor2Dyn)                         \
    V(NegDyn)                          \
    V(NotDyn)                          \
    V(IncDyn)                          \
    V(DecDyn)                          \
    V(ExpDyn)                          \
    V(ThrowDyn)                        \
    V(LdObjByIndexDyn)                 \
    V(StObjByIndexDyn)                 \
    V(LdObjByNameDyn)                  \
    V(StObjByNameDyn)                  \
    V(LdObjByValueDyn)                 \
    V(StObjByValueDyn)                 \
    V(StOwnByNameDyn)                  \
    V(StOwnByIdDyn)                    \
    V(StOwnByValueDyn)                 \
    V(Trygetobjprop)                   \
    V(Delobjprop)                      \
    V(Defineglobalvar)                 \
    V(Definelocalvar)                  \
    V(Definefuncexpr)                  \
    V(DefinefuncDyn)                   \
    V(DefineNCFuncDyn)                 \
    V(NewobjDynrange)                  \
    V(RefeqDyn)                        \
    V(TypeofDyn)                       \
    V(LdnewobjrangeDyn)                \
    V(IsInDyn)                         \
    V(InstanceofDyn)                   \
    V(NewobjspreadDyn)                 \
    V(CallArg0Dyn)                     \
    V(CallArg1Dyn)                     \
    V(CallArg2Dyn)                     \
    V(CallArg3Dyn)                     \
    V(CallThisRangeDyn)                \
    V(CallRangeDyn)                    \
    V(CallSpreadDyn)                   \
    V(NewlexenvDyn)                    \
    V(CopylexenvDyn)                   \
    V(StLexVarDyn)                     \
    V(StLexDyn)                        \
    V(LdLexVarDyn)                     \
    V(LdLexDyn)                        \
    V(LdlexenvDyn)                     \
    V(GetPropIterator)                 \
    V(CreateIterResultObj)             \
    V(DefineGeneratorFunc)             \
    V(SuspendGenerator)                \
    V(SuspendAsyncGenerator)           \
    V(ResumeGenerator)                 \
    V(GetResumeMode)                   \
    V(CreateGeneratorObj)              \
    V(SetGeneratorState)               \
    V(CreateAsyncGeneratorObj)         \
    V(DefineAsyncFunc)                 \
    V(DefineGetterSetterByValue)       \
    V(DefineAsyncGeneratorFunc)        \
    V(AsyncFunctionEnter)              \
    V(AsyncFunctionAwait)              \
    V(AsyncFunctionResolve)            \
    V(AsyncFunctionReject)             \
    V(AsyncGeneratorResolve)           \
    V(AsyncGeneratorReject)            \
    V(ThrowUndefined)                  \
    V(ThrowConstAssignment)            \
    V(ThrowTdz)                        \
    V(Copyrestargs)                    \
    V(Trystobjprop)                    \
    V(GetMethod)                       \
    V(GetTemplateObject)               \
    V(GetIterator)                     \
    V(GetAsyncIterator)                \
    V(ThrowIfNotObject)                \
    V(ThrowThrowNotExists)             \
    V(CreateObjectWithExcludedKeys)    \
    V(ThrowPatternNonCoercible)        \
    V(IterNext)                        \
    V(CloseIterator)                   \
    V(StArraySpread)                   \
    V(GetCallSpreadArgs)               \
    V(LoadICByName)                    \
    V(LoadMissedICByName)              \
    V(GetPropertyByName)               \
    V(LoadICByValue)                   \
    V(LoadMissedICByValue)             \
    V(StoreICByName)                   \
    V(StoreMissedICByName)             \
    V(StoreICByValue)                  \
    V(StoreMissedICByValue)            \
    V(NotifyInlineCache)               \
    V(CompressCollector_RunPhases)     \
    V(MixSpaceCollector_RunPhases)     \
    V(SemiSpaceCollector_RunPhases)    \
    V(LoadGlobalICByName)              \
    V(StoreGlobalICByName)             \
    V(StoreICWithHandler)              \
    V(StorePrototype)                  \
    V(StoreWithTransition)             \
    V(StoreField)                      \
    V(StoreGlobal)                     \
    V(LoadPrototype)                   \
    V(LoadICWithHandler)               \
    V(StoreElement)                    \
    V(CallGetter)                      \
    V(CallSetter)                      \
    V(AddPropertyByName)               \
    V(AddPropertyByIndex)              \
    V(GetPropertyByIndex)              \
    V(GetPropertyByValue)              \
    V(SetPropertyByIndex)              \
    V(SetPropertyByValue)              \
    V(FastTypeOf)                      \
    V(FastSetPropertyByIndex)          \
    V(FastSetPropertyByValue)          \
    V(FastGetPropertyByName)           \
    V(FastGetPropertyByValue)          \
    V(FastGetPropertyByIndex)          \
    V(NewLexicalEnvDyn)                \
    V(SetElement)                      \
    V(SetGlobalOwnProperty)            \
    V(SetOwnPropertyByName)            \
    V(SetOwnElement)                   \
    V(FastSetProperty)                 \
    V(FastGetProperty)                 \
    V(FindOwnProperty)                 \
    V(HasOwnProperty)                  \
    V(ExecuteNative)                   \
    V(Execute)                         \
    V(ToJSTaggedValueWithInt32)        \
    V(ToJSTaggedValueWithUint32)       \
    V(ThrowIfSuperNotCorrectCall)      \
    V(CreateEmptyArray)                \
    V(CreateEmptyObject)               \
    V(CreateObjectWithBuffer)          \
    V(CreateObjectHavingMethod)        \
    V(SetObjectWithProto)              \
    V(ImportModule)                    \
    V(StModuleVar)                     \
    V(CopyModule)                      \
    V(LdModvarByName)                  \
    V(CreateRegExpWithLiteral)         \
    V(CreateArrayWithBuffer)           \
    V(GetNextPropName)                 \
    V(CopyDataProperties)              \
    V(GetUnmapedArgs)                  \
    V(TryStGlobalByName)               \
    V(LdGlobalVar)                     \
    V(StGlobalVar)                     \
    V(ThrowReferenceError)             \
    V(ThrowTypeError)                  \
    V(ThrowSyntaxError)                \
    V(NewClassFunc)                    \
    V(ClassFieldAdd)                   \
    V(DefineClassPrivateFields)        \
    V(ClassPrivateMethodOrAccessorAdd) \
    V(ClassPrivateFieldAdd)            \
    V(ClassPrivateFieldGet)            \
    V(ClassPrivateFieldSet)            \
    V(ClassPrivateFieldIn)             \
    V(SuperCall)                       \
    V(SuperCallSpread)                 \
    V(DefineMethod)                    \
    V(LdSuperByValue)                  \
    V(StSuperByValue)                  \
    V(ThrowDeleteSuperProperty)        \
    V(GetIteratorNext)                 \
    V(ModWithTSType)                   \
    V(MulWithTSType)                   \
    V(SubWithTSType)                   \
    V(DivWithTSType)                   \
    V(AddWithTSType)                   \
    V(GetBitOPDate)                    \
    V(ShlWithTSType)                   \
    V(ShrWithTSType)                   \
    V(AshrWithTSType)                  \
    V(AndWithTSType)                   \
    V(OrWithTSType)                    \
    V(XorWithTSType)                   \
    V(EqualWithIC)                     \
    V(NotEqualWithIC)                  \
    V(Compare)                         \
    V(LessDynWithIC)                   \
    V(LessEqDynWithIC)                 \
    V(GreaterDynWithIC)                \
    V(GreaterEqDynWithIC)              \
    V(SetPropertyByName)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define BUILTINS_API_LIST(V)          \
    V(ArrayList, Constructor)         \
    V(ArrayList, Add)                 \
    V(ArrayList, Iterator)            \
    V(Boolean, ThisBooleanValue)      \
    V(Proxy, InvalidateProxyFunction) \
    V(DataView, GetViewValue)         \
    V(DataView, SetViewValue)         \
    V(Symbol, ThisSymbolValue)        \
    V(Number, ThisNumberValue)        \
    V(Object, GetOwnPropertyKeys)     \
    V(Object, LookupDesc)             \
    V(Object, GetBuiltinTag)

// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define ABSTRACT_OPERATION_LIST(V) V(JSTaggedValue, ToString)

// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define INTERPRETER_CALLER_ID(name) INTERPRETER_ID_##name,
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define BUILTINS_API_ID(class, name) BUILTINS_ID_##class##_##name,
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define GC_RUNPHASE_ID(name) name##_GC_TRACE_RUNPHASE,
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define ABSTRACT_OPERATION_ID(class, name) ABSTRACT_ID_##class##_##name,

enum EcmaRuntimeCallerId {
    INTERPRETER_CALLER_LIST(INTERPRETER_CALLER_ID)
#define BUILTINS_MACRO_GEN_V BUILTINS_API_ID
#include "plugins/ecmascript/runtime/builtins/generated/builtins_ids_gen.inl"
#undef BUILTINS_MACRO_GEN_V
        BUILTINS_API_LIST(BUILTINS_API_ID) ABSTRACT_OPERATION_LIST(ABSTRACT_OPERATION_ID) RUNTIME_CALLER_NUMBER,
};

#if ECMASCRIPT_ENABLE_RUNTIME_STAT
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define INTERPRETER_TRACE(thread, name)                                                        \
    [[maybe_unused]] JSThread *_js_thread_ = thread;                                           \
    [[maybe_unused]] EcmaRuntimeStat *_run_stat_ = _js_thread_->GetEcmaVM()->GetRuntimeStat(); \
    RuntimeTimerScope interpret_##name##_scope_(thread, INTERPRETER_CALLER_ID(name) _run_stat_)

// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define BUILTINS_API_TRACE(thread, class, name)                                                \
    [[maybe_unused]] JSThread *_js_thread_ = thread;                                           \
    [[maybe_unused]] EcmaRuntimeStat *_run_stat_ = _js_thread_->GetEcmaVM()->GetRuntimeStat(); \
    RuntimeTimerScope builtins_##class##name##_scope_(thread, BUILTINS_API_ID(class, name) _run_stat_)

// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define ABSTRACT_OPERATION_TRACE(thread, class, name)                                          \
    [[maybe_unused]] JSThread *_js_thread_ = thread;                                           \
    [[maybe_unused]] EcmaRuntimeStat *_run_stat_ = _js_thread_->GetEcmaVM()->GetRuntimeStat(); \
    RuntimeTimerScope abstract_##class##name##_scope_(thread, ABSTRACT_OPERATION_ID(class, name) _run_stat_)

#else
#define INTERPRETER_TRACE(thread, name) static_cast<void>(0)                // NOLINT(cppcoreguidelines-macro-usage)
#define BUILTINS_API_TRACE(thread, class, name) static_cast<void>(0)        // NOLINT(cppcoreguidelines-macro-usage)
#define ABSTRACT_OPERATION_TRACE(thread, class, name) static_cast<void>(0)  // NOLINT(cppcoreguidelines-macro-usage)
#endif                                                                      // ECMASCRIPT_ENABLE_RUNTIME_STAT
}  // namespace ark::ecmascript
#endif
